{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Clone a Group \n",
    "\n",
    "This sample notebook can be used for cloning one or more groups, either on the same portal or from one portal to another.\n",
    "\n",
    "**Note:** If you want to clone all portal users, groups and content refer to the sample \n",
    "[Clone Portal users, groups and content](clone_portal_users_groups_and_content.ipynb)\n",
    "\n",
    "In this sample, we will clone the [Vector Basemaps](http://www.arcgis.com/home/group.html?id=30de8da907d240a0bccd5ad3ff25ef4a) group from ArcGIS Online to an ArcGIS Enterprise."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "toc": true
   },
   "source": [
    "<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n",
    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Clone-a-Group\" data-toc-modified-id=\"Clone-a-Group-1\"><span class=\"toc-item-num\">1&nbsp;&nbsp;</span>Clone a Group</a></span><ul class=\"toc-item\"><li><span><a href=\"#Define-the-source-and-target-portals\" data-toc-modified-id=\"Define-the-source-and-target-portals-1.1\"><span class=\"toc-item-num\">1.1&nbsp;&nbsp;</span>Define the source and target portals</a></span></li><li><span><a href=\"#Search-for-the-group-and-its-contents-in-the-source-portal\" data-toc-modified-id=\"Search-for-the-group-and-its-contents-in-the-source-portal-1.2\"><span class=\"toc-item-num\">1.2&nbsp;&nbsp;</span>Search for the group and its contents in the source portal</a></span></li><li><span><a href=\"#Clone-the-group-in-the-target-portal-if-it-does-not-already-exist.\" data-toc-modified-id=\"Clone-the-group-in-the-target-portal-if-it-does-not-already-exist.-1.3\"><span class=\"toc-item-num\">1.3&nbsp;&nbsp;</span>Clone the group in the target portal if it does not already exist.</a></span></li><li><span><a href=\"#Clone-the-contents-of-the-group-to-the-target-portal\" data-toc-modified-id=\"Clone-the-contents-of-the-group-to-the-target-portal-1.4\"><span class=\"toc-item-num\">1.4&nbsp;&nbsp;</span>Clone the contents of the group to the target portal</a></span></li></ul></li></ul></div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from arcgis.gis import GIS\n",
    "from IPython.display import display\n",
    "from arcgis.gis import ItemProperties"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define the source and target portals\n",
    "\n",
    "To start with, define the source and target portals."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# an anonymous connection to ArcGIS Online is sufficient, \n",
    "# since we are cloning a public group\n",
    "source = GIS()\n",
    "\n",
    "target = GIS(profile=\"your_organization_profile\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Search for the group and its contents in the source portal\n",
    "In the source portal, search for the group to be cloned. In our case the title of the group is 'Vector Basemaps'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Group title:\"OpenStreetMap Vector Basemap\" owner:esri>,\n",
       " <Group title:\"United States Vector Tile Layers\" owner:esri>,\n",
       " <Group title:\"Vector Basemaps\" owner:esri>,\n",
       " <Group title:\"Vector Basemaps (for Export)\" owner:esri>]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "source_groups = source.groups.search(\"title:Vector Basemaps AND owner:esri\", outside_org = True)\n",
    "source_groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://www.arcgis.com/home/group.html?id=30de8da907d240a0bccd5ad3ff25ef4a' target='_blank'>\n",
       "                        <img src='https://www.arcgis.com/sharing/rest/community/groups/30de8da907d240a0bccd5ad3ff25ef4a/info/Esri_Logo_13.jpg' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://www.arcgis.com/home/group.html?id=30de8da907d240a0bccd5ad3ff25ef4a' target='_blank'><b>Vector Basemaps</b>\n",
       "                        </a>\n",
       "                        <br/>\n",
       "                        <br/><b>Summary</b>: This group contains a set of Esri vector basemaps that are available for use in ArcGIS Online.  The group contains both web maps and tile layers. \n",
       "                        <br/><b>Description</b>: <div>For several years, Esri has made available a suite of basemaps that can be used through ArcGIS Online and other apps to create maps and apps. These multi-scale basemaps have been delivered as pre-rendered image tiles (JPG or PNG format) to optimize performance. These basemaps have proven to be very useful and popular, with several billion tiles served each month, but they have some limitations (e.g. users can not customize map, low-res image tiles not optimal for display on high-res devices, etc.).</div><div><br /></div><div>To provide additional options for users, Esri has introduced a new set of vector basemaps. These basemaps are delivered as vector tiles (PBF format) that are rendered client-side based on a style file that is delivered with the vector tiles. Vector basemaps are available in Map Viewer and Scene Viewer, as well as in ArcGIS Pro, configurable apps that include a basemap gallery, Workforce for ArcGIS, Explorer for ArcGIS, and apps created using Web AppBuilder. To find out whether vector basemaps are available in a specific ArcGIS app, refer to the app documentation. Users are able to customize the look and feel of the vector basemaps by creating custom styles that are used to render the vector tiles.</div><div><br /></div><div><b>Available Vector Basemaps</b></div><div><br /></div><div>This group includes vector basemaps in multiple styles, some that closely resemble existing Esri basemaps (e.g. Streets, Topographic, Light and Dark Gray Canvas, Terrain with Labels), and others that are new (e.g. Streets at Night, Navigation, and Imagery Hybrid).  The group also includes several more 'creative' styles (e.g. Colored Pencil, Charted Territory, Mid-Century, Modern Antique) that are optimized for specific uses.  It also includes a new OpenStreetMap vector basemap created and hosted by Esri.  The vector basemaps are available as both web maps, which can be used as a basemap for adding other layers, and as tile layers, which can be added to existing maps either as a basemap or overlay layer.</div><div><br /></div><div><b>Learn More</b></div><div><br /></div><div>To learn more, including how you can customize the Esri vector basemaps, you can refer to the blog posts tagged with &quot;<a href='https://www.esri.com/arcgis-blog/?s=#vector+basemaps' target='_blank'>vector basemaps</a>&quot;.  You can also use the new <a href='https://developers.arcgis.com/vector-tile-style-editor/' target='_blank'>Vector Tile Style Editor app</a> to quickly create your own custom map.  The Vector Tile Style Editor app has now been integrated with ArcGIS Online so it is accessible from vector tile layer items in the ArcGIS.com Map Viewer.</div>\n",
       "                        <br/><b>Owner</b>: esri\n",
       "                        <br/><b>Created</b>: October 27, 2015\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<Group title:\"Vector Basemaps\" owner:esri>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "source_group = source_groups[2]\n",
    "source_group"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "List the items that are a part of the group 'Vector Basemaps'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Item title:\"Colored Pencil Map\" type:Web Map owner:esri>]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "source_items = source_group.content()\n",
    "source_items"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clone the group in the target portal if it does not already exist. \n",
    "\n",
    "We create a new group in the target portal with all the properties of the group in the source portal. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://rpubw120iwapt.ags.esri.com/portal/home/group.html?id=84664d956490472f89d7ba14a84fbed8' target='_blank'>\n",
       "                        <img src='' ' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://rpubw120iwapt.ags.esri.com/portal/home/group.html?id=84664d956490472f89d7ba14a84fbed8' target='_blank'><b>Vector Basemaps</b>\n",
       "                        </a>\n",
       "                        <br/>\n",
       "                        <br/><b>Summary</b>: This group contains a set of Esri vector basemaps that are available for use in ArcGIS Online.  The group contains both web maps and tile layers. \n",
       "                        <br/><b>Description</b>: <div>For several years, Esri has made available a suite of basemaps that can be used through ArcGIS Online and other apps to create maps and apps. These multi-scale basemaps have been delivered as pre-rendered image tiles (JPG or PNG format) to optimize performance. These basemaps have proven to be very useful and popular, with several billion tiles served each month, but they have some limitations (e.g. users can not customize map, low-res image tiles not optimal for display on high-res devices, etc.).</div><div><br /></div><div>To provide additional options for users, Esri has introduced a new set of vector basemaps. These basemaps are delivered as vector tiles (PBF format) that are rendered client-side based on a style file that is delivered with the vector tiles. Vector basemaps are available in Map Viewer and Scene Viewer, as well as in ArcGIS Pro, configurable apps that include a basemap gallery, Workforce for ArcGIS, Explorer for ArcGIS, and apps created using Web AppBuilder. To find out whether vector basemaps are available in a specific ArcGIS app, refer to the app documentation. Users are able to customize the look and feel of the vector basemaps by creating custom styles that are used to render the vector tiles.</div><div><br /></div><div><b>Available Vector Basemaps</b></div><div><br /></div><div>This group includes vector basemaps in multiple styles, some that closely resemble existing Esri basemaps (e.g. Streets, Topographic, Light and Dark Gray Canvas, Terrain with Labels), and others that are new (e.g. Streets at Night, Navigation, and Imagery Hybrid).  The group also includes several more 'creative' styles (e.g. Colored Pencil, Charted Territory, Mid-Century, Modern Antique) that are optimized for specific uses.  It also includes a new OpenStreetMap vector basemap created and hosted by Esri.  The vector basemaps are available as both web maps, which can be used as a basemap for adding other layers, and as tile layers, which can be added to existing maps either as a basemap or overlay layer.</div><div><br /></div><div><b>Learn More</b></div><div><br /></div><div>To learn more, including how you can customize the Esri vector basemaps, you can refer to the blog posts tagged with &quot;<a href='https://www.esri.com/arcgis-blog/?s=#vector+basemaps' target='_blank' rel='nofollow ugc noopener noreferrer'>vector basemaps</a>&quot;.  You can also use the new <a href='https://developers.arcgis.com/vector-tile-style-editor/' target='_blank' rel='nofollow ugc noopener noreferrer'>Vector Tile Style Editor app</a> to quickly create your own custom map.  The Vector Tile Style Editor app has now been integrated with ArcGIS Online so it is accessible from vector tile layer items in the ArcGIS.com Map Viewer.</div>\n",
       "                        <br/><b>Owner</b>: esri\n",
       "                        <br/><b>Created</b>: July 08, 2025\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<Group title:\"Vector Basemaps\" owner:esri>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import tempfile\n",
    "if not target.groups.search('Vector Basemaps'):\n",
    "    try:\n",
    "        with tempfile.TemporaryDirectory() as temp_dir:\n",
    "            thumbnail_file = source_group.download_thumbnail(temp_dir)\n",
    "            \n",
    "            #create a group in the target portal with all the properties of the group in the source\n",
    "            target_group = target.groups.create(title = source_group.title,\n",
    "                                                 tags = source_group.tags,\n",
    "                                                 description = source_group.description,\n",
    "                                                 snippet = source_group.snippet,\n",
    "                                                 access = source_group.access, \n",
    "                                                 thumbnail= thumbnail_file,\n",
    "                                                 is_invitation_only = True,\n",
    "                                                 sort_field = 'avgRating',\n",
    "                                                 sort_order ='asc',\n",
    "                                                 is_view_only=True)\n",
    "            #display the group\n",
    "            display(target_group)\n",
    "            \n",
    "    except Exception as e:\n",
    "        print('Group {} could not be created'.format(source_group.title))\n",
    "        print(e)\n",
    "else:\n",
    "    print('Group {} already exists in the portal'.format(source_group.title))\n",
    "    target_group = target.groups.search('Vector Basemaps')[0]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clone the contents of the group to the target portal\n",
    "It is possible that some items to be cloned may already be present on the target portal. In such a situation, we simply share those items with the target group. Thus, in the section below, we renew our list of items to be cloned by removing from it, any item that was existing on the target portal beforehand."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "#making a list for the items to be cloned in the target portal\n",
    "items_to_be_cloned = list(source_items)\n",
    "\n",
    "#checking for the presence of the item in the target portal \n",
    "for item in source_items:\n",
    "    searched_items = target.content.search(query='title:'+item.title, item_type = item.type)   \n",
    "    \n",
    "    for s_item in searched_items:\n",
    "        \n",
    "        if s_item.title == item.title:\n",
    "            \n",
    "            #if an item is not a part of the group in the target portal then share it \n",
    "            if s_item not in target_group.content():\n",
    "                s_item.sharing.groups.add(\n",
    "                    group=target_group\n",
    "                )\n",
    "            \n",
    "            #remove the already existing item from the list of items to be cloned\n",
    "            items_to_be_cloned.remove(item)                \n",
    "            \n",
    "            #display the item\n",
    "            display(s_item)      \n",
    "                     \n",
    "            break\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note:** The [GroupManager.clone()](https://developers.arcgis.com/python/latest/api-reference/arcgis.gis.toc.html#arcgis.gis.GroupManager.clone) doesn't clone the group’s items, it only recreates groups from site A to site B. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now after having removed the existing items from the list of items to be cloned, we can easily copy the remaining content of the source group to the newly created group in the target portal.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://rpubw120iwapt.ags.esri.com/portal/home/item.html?id=826498a48bd0424f9c9315214f2165d4' target='_blank'>\n",
       "                        <img src='https://rpubw120iwapt.ags.esri.com/portal/portalimages/desktopapp.png' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\"     style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://rpubw120iwapt.ags.esri.com/portal/home/item.html?id=826498a48bd0424f9c9315214f2165d4' target='_blank'><b>Colored Pencil Map</b>\n",
       "                        </a>\n",
       "                        <br/>This world basemap features symbolized with the appearance of being hand-drawn by colored pencils. (World Edition)<br/><img src='https://rpubw120iwapt.ags.esri.com/portal/home/js/jsapi/esri/css/images/item_type_icons/maps16.png' style=\"vertical-align:middle;\" width=16 height=16>Web Map by esri\n",
       "                        <br/>Last Modified: July 08, 2025\n",
       "                        <br/>0 comments, 0 views\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<Item title:\"Colored Pencil Map\" type:Web Map owner:esri>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#cloning all items that were not present on the portal before\n",
    "for item in items_to_be_cloned:    \n",
    "    try:\n",
    "        thumbnail_file = item.download_thumbnail()\n",
    "        target_item_properties = ItemProperties(title=item.title,\n",
    "                              tags=item.tags,\n",
    "                              text=item.get_data(try_json=True),\n",
    "                              item_type=item.type,\n",
    "                              snippet=item.snippet,\n",
    "                              description=item.description,\n",
    "                              thumbnail=thumbnail_file)        \n",
    "        #create an item\n",
    "        root_folder = target.content.folders.get()\n",
    "        job = root_folder.add(item_properties=target_item_properties, item_id=item.id)\n",
    "        target_item = job.result()\n",
    "        #share that item with the group on the target portal\n",
    "        target_item.sharing.groups.add(\n",
    "            group=target_group\n",
    "        )\n",
    "        \n",
    "        #display the item\n",
    "        display(target_item)\n",
    "            \n",
    "    except Exception as e:\n",
    "        print('Item {} could not be created in the target portal'.format(item.title))\n",
    "        print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Please see [GroupMigrationManager](https://developers.arcgis.com/python/latest/api-reference/arcgis.gis.toc.html#groupmigrationmanager) for offline exporting of group items"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": true,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "293.594px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
